﻿Imports System.Text

Public Class Subtitles

    Private subTextParts(2) As String
    Private thirdPart As String
    Private currentLine As String
    Private currentIndex As Integer
    Private subsFileReader As System.IO.StreamReader
    Private subsFileWriter As System.IO.StreamWriter
    Private subsCount As Integer
    Private subEncoding As System.Text.Encoding
    Private subFormat As String

    Public Structure SubtitleType
        Public ID As Integer
        Public showTime As String
        Public showTimeInMS As Integer
        Public hideTime As String
        Public hideTimeInMS As Integer
        Public text As String
        Public translationText As String
        Public isBold As String
        Public isItalic As String
        Public propertiesString As String
    End Structure

    ' Declare array to hold all subtitles
    Private SubtitleArray As SubtitleType() = New SubtitleType() {}

    ' Constructor
    Sub New()

    End Sub

    ' Public Functions and Methods
    Public Function getAll(ByVal index As Integer) As SubtitleType
        Return SubtitleArray(index)
    End Function

    Public Sub setAll(ByVal index As Integer, ByVal subtitle As SubtitleType)
        Try
            SubtitleArray(index) = subtitle
        Catch ex As IndexOutOfRangeException
            ReDim Preserve SubtitleArray(index)
            SubtitleArray(index) = subtitle
        End Try

        setShowTimeInMS(index, subtitle.showTimeInMS)
        setHideTimeInMS(index, subtitle.hideTimeInMS)

    End Sub

    Public Function getAllbyID(ByVal myID As Integer) As SubtitleType
        Dim index As Integer
        For i = 0 To SubtitleArray.Count - 1
            If SubtitleArray(i).ID = myID Then
                index = i
                Exit For
            End If
        Next
        Return SubtitleArray(index)
    End Function

    Public Function getID(ByVal index As Integer) As Integer
        Return SubtitleArray(index).ID
    End Function

    Public Sub setID(ByVal index As Integer, ByVal myID As Integer)
        SubtitleArray(index).ID = myID
    End Sub

    Public Function getShowTime(ByVal index As Integer) As String
        Return SubtitleArray(index).showTime
    End Function

    Public Sub setShowTime(ByVal index As Integer, ByVal myShowTime As String)
        SubtitleArray(index).showTime = myShowTime
        SubtitleArray(index).showTimeInMS = convertShowHideCellToMiliseconds(myShowTime)
    End Sub

    Public Function getShowTimeInMS(ByVal index As Integer) As Integer
        Return SubtitleArray(index).showTimeInMS
    End Function

    Public Sub setShowTimeInMS(ByVal index As Integer, ByVal myshowTimeInMS As Integer)
        SubtitleArray(index).showTimeInMS = myshowTimeInMS
        SubtitleArray(index).showTime = convertMilisecondsToShowHideCell(myshowTimeInMS)
    End Sub

    Public Function getHideTime(ByVal index As Integer) As String
        Return SubtitleArray(index).hideTime
    End Function

    Public Sub setHideTime(ByVal index As Integer, ByVal myHideTime As String)
        SubtitleArray(index).hideTime = myHideTime
        SubtitleArray(index).hideTimeInMS = convertShowHideCellToMiliseconds(myHideTime)
    End Sub

    Public Function getHideTimeInMS(ByVal index As Integer) As Integer
        Return SubtitleArray(index).hideTimeInMS
    End Function

    Public Sub setHideTimeInMS(ByVal index As Integer, ByVal myHideTimeInMS As Integer)
        SubtitleArray(index).hideTimeInMS = myHideTimeInMS
        SubtitleArray(index).hideTime = convertMilisecondsToShowHideCell(myHideTimeInMS)
    End Sub

    Public Function getText(ByVal index As Integer) As String
        Return SubtitleArray(index).text
    End Function

    Public Sub setText(ByVal index As Integer, ByVal myText As String)
        SubtitleArray(index).text = myText
    End Sub

    Public Function getTranslationText(ByVal index As Integer) As String
        Return SubtitleArray(index).translationText
    End Function

    Public Sub setTranslationText(ByVal index As Integer, ByVal myTranslationText As String)
        SubtitleArray(index).translationText = myTranslationText
    End Sub

    Public Function getIsBold(ByVal index As Integer) As Boolean
        Return SubtitleArray(index).isBold
    End Function

    Public Sub setIsBold(ByVal index As Integer, ByVal myIsBold As Boolean)
        SubtitleArray(index).isBold = myIsBold
    End Sub

    Public Function getIsItalic(ByVal index As Integer) As Boolean
        Return SubtitleArray(index).isItalic
    End Function

    Public Sub setIsItalic(ByVal index As Integer, ByVal myIsItalic As Boolean)
        SubtitleArray(index).isItalic = myIsItalic
    End Sub

    Public Function getPropertiesString(ByVal index As Integer) As String
        Return SubtitleArray(index).propertiesString
    End Function

    Public Sub setPropertiesString(ByVal index As Integer, ByVal myPropertiesString As String)
        SubtitleArray(index).propertiesString = myPropertiesString
    End Sub

    Public Sub getAllExts()
        Dim fileWord As String
        fileWord = loadStringFromLangFile("fileWord")
        frmMain.dlgSubOpen.Filter = "SubRip " & fileWord & " (*.srt)|*.srt|" & _
                                    "Text " & fileWord & " (*.txt)|*.txt|" & _
                                    "Any " & fileWord & " (*.*)|*.*"
        frmMain.dlgSubSave.Filter = frmMain.dlgSubOpen.Filter
    End Sub

    Public Sub clear()
        SubtitleArray = New SubtitleType() {}
    End Sub

    Public Function getSubFormat() As String
        Return subFormat
    End Function

    Public Sub setSubFormat(ByVal mySubFormat As String)
        subFormat = mySubFormat
    End Sub

    Public Function getSubEncoding() As System.Text.Encoding
        Return subEncoding
    End Function

    Public Sub setSubEncoding(ByVal mySubEncoding As System.Text.Encoding)
        subEncoding = mySubEncoding
    End Sub

    ''' <summary>
    ''' Opens a FileOpen dialog and continues to open the subtitle file, load it into the
    ''' frmMain.mySubtitles array and the DataGridView.
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub open()
        Dim failed As Boolean = False

        ' Get extensions OSE supports.
        getAllExts()

        ' If user picks a file, continue.
        If frmMain.dlgSubOpen.ShowDialog = DialogResult.OK Then
            ' Disable display of subtitles while loading a new file.
            If frmMain.mPlayer.playState = WMPLib.WMPPlayState.wmppsPlaying Then
                frmMain.TimerSub.Enabled = False
            End If

            ' Guess the subtitle format from the file extension.
            Select Case LCase(Microsoft.VisualBasic.Right(frmMain.dlgSubOpen.FileName, 3))
                Case "srt"
                    subFormat = "SubRip"
                Case Else
                    subFormat = "Unknown"
                    failed = True
            End Select

            ' See if there's a Unicode BOM.
            Dim binaryReader As New System.IO.BinaryReader(System.IO.File.OpenRead(frmMain.dlgSubOpen.FileName))

            Dim first As Byte = binaryReader.ReadByte
            Dim second As Byte = binaryReader.ReadByte

            If first = Convert.ToByte("FF", 16) And second = Convert.ToByte("FE", 16) Then
                subEncoding = Encoding.Unicode
            ElseIf first = Convert.ToByte("FE", 16) And second = Convert.ToByte("FF", 16) Then
                subEncoding = Encoding.BigEndianUnicode
            ElseIf first = Convert.ToByte("EF", 16) And second = Convert.ToByte("BB", 16) Then
                subEncoding = Encoding.UTF8
            Else
                ' If the file's not Unicode...
                subEncoding = Encoding.Default
                failed = True
            End If

            binaryReader.Close()

            ' If the subtitle format isn't certain and/or the encoding isn't unicode, we ask the user
            ' to pick for themselves.
            If failed Then
                frmUnknownFormat.ShowDialog(frmMain)
                If frmUnknownFormat.DialogResult = DialogResult.Cancel Then
                    If frmMain.mPlayer.playState = WMPLib.WMPPlayState.wmppsPaused Or frmMain.mPlayer.playState = WMPLib.WMPPlayState.wmppsPlaying Then
                        frmMain.findSubForCurrentTime()
                        frmMain.TimerSub.Enabled = True
                    End If
                    Exit Sub
                End If
            End If

            Dim startTime As Date = Now

            subsFileReader = My.Computer.FileSystem.OpenTextFileReader(frmMain.dlgSubOpen.FileName, subEncoding)

            frmMain.dgvSubtitles.Rows.Clear()
            clear()

            Select Case subFormat
                Case "SubRip"
                    LoadSRTSubRip()
            End Select

            passArrayToDataGridView()

            subsFileReader.Close()

            updateTitle()

            If frmMain.mPlayer.playState = WMPLib.WMPPlayState.wmppsPaused Or frmMain.mPlayer.playState = WMPLib.WMPPlayState.wmppsPlaying Then
                frmMain.findSubForCurrentTime()
                frmMain.TimerSub.Enabled = True
            End If

            frmMain.CheckForOverlappingSubtitlesToolStripMenuItem.PerformClick()

            resetFPSsetting()

            frmMain.dgvSubtitles_SelectionChanged(Nothing, Nothing)

            Dim endTime As Date = Now
            addToDebugList(loadStringFromLangFile("parsedgen") & " " & subsCount & " " & _
                           loadStringFromLangFile("subsgen") & " " & _
                           loadStringFromLangFile("in_somany_seconds1") & " " & (endTime - startTime).Seconds.ToString & "." & _
                           (endTime - startTime).Milliseconds.ToString("000") & " " & _
                           loadStringFromLangFile("in_somany_seconds2"))
        End If
    End Sub

    Public Sub save()
        getAllExts()

        If frmMain.dlgSubSave.ShowDialog = DialogResult.OK Then
            Dim startTime As Date = Now

            passDataGridViewToArray()

            fileWriter = My.Computer.FileSystem.OpenTextFileWriter(frmMain.dlgSubSave.FileName, False, subEncoding)

            Select Case LCase(Microsoft.VisualBasic.Right(frmMain.dlgSubSave.FileName, 3))
                Case "srt"
                    SaveSRTSubRip()
            End Select

            fileWriter.Close()

            frmMain.dlgSubOpen.FileName = frmMain.dlgSubSave.FileName
            updateTitle()

            Dim endTime As Date = Now
            addToDebugList(loadStringFromLangFile("parsedgen") & " " & subsCount & " " & _
                           loadStringFromLangFile("subsgen") & " " & _
                           loadStringFromLangFile("in_somany_seconds1") & " " & (endTime - startTime).Seconds.ToString & "." & _
                           (endTime - startTime).Milliseconds.ToString("000") & " " & _
                           loadStringFromLangFile("in_somany_seconds2"))
        End If

    End Sub

    Private Sub parseProperties(ByRef subTextParts() As String)

        Dim finalPart As Short = subTextParts.Length - 1

        If Microsoft.VisualBasic.Left(subTextParts(0), 3) = "<b>" And Microsoft.VisualBasic.Right(subTextParts(finalPart), 4) = "</b>" Then
            SubtitleArray(currentIndex).isBold = True
            subTextParts(0) = Microsoft.VisualBasic.Right(subTextParts(0), subTextParts(0).Length - 3)
            subTextParts(finalPart) = Microsoft.VisualBasic.Left(subTextParts(finalPart), subTextParts(finalPart).Length - 4)
            If Microsoft.VisualBasic.Left(subTextParts(0), 3) = "<i>" And Microsoft.VisualBasic.Right(subTextParts(finalPart), 4) = "</i>" Then
                SubtitleArray(currentIndex).isItalic = True
                subTextParts(0) = Microsoft.VisualBasic.Right(subTextParts(0), subTextParts(0).Length - 3)
                subTextParts(finalPart) = Microsoft.VisualBasic.Left(subTextParts(finalPart), subTextParts(finalPart).Length - 4)
            End If
        Else
            SubtitleArray(currentIndex).isBold = False
        End If

        If Microsoft.VisualBasic.Left(subTextParts(0), 3) = "<i>" And Microsoft.VisualBasic.Right(subTextParts(finalPart), 4) = "</i>" Then
            SubtitleArray(currentIndex).isItalic = True
            subTextParts(0) = Microsoft.VisualBasic.Right(subTextParts(0), subTextParts(0).Length - 3)
            subTextParts(finalPart) = Microsoft.VisualBasic.Left(subTextParts(finalPart), subTextParts(finalPart).Length - 4)
            If Microsoft.VisualBasic.Left(subTextParts(0), 3) = "<b>" And Microsoft.VisualBasic.Right(subTextParts(finalPart), 4) = "</b>" Then
                SubtitleArray(currentIndex).isBold = True
                subTextParts(0) = Microsoft.VisualBasic.Right(subTextParts(0), subTextParts(0).Length - 3)
                subTextParts(finalPart) = Microsoft.VisualBasic.Left(subTextParts(finalPart), subTextParts(finalPart).Length - 4)
            End If
        Else
            SubtitleArray(currentIndex).isItalic = False
        End If

        convertPropertiesToPropertiesString()

    End Sub

    Public Sub convertPropertiesToPropertiesString()

        If SubtitleArray(currentIndex).isBold = True And SubtitleArray(currentIndex).isItalic = True Then
            SubtitleArray(currentIndex).propertiesString = "BI"
        ElseIf SubtitleArray(currentIndex).isBold = True And SubtitleArray(currentIndex).isItalic = False Then
            SubtitleArray(currentIndex).propertiesString = "B"
        ElseIf SubtitleArray(currentIndex).isBold = False And SubtitleArray(currentIndex).isItalic = True Then
            SubtitleArray(currentIndex).propertiesString = "I"
        ElseIf SubtitleArray(currentIndex).isBold = False And SubtitleArray(currentIndex).isItalic = False Then
            SubtitleArray(currentIndex).propertiesString = ""
        End If

    End Sub

    Public Sub convertPropertiesToPropertiesString(ByVal index As Integer)

        If SubtitleArray(index).isBold = True And SubtitleArray(index).isItalic = True Then
            SubtitleArray(index).propertiesString = "BI"
        ElseIf SubtitleArray(index).isBold = True And SubtitleArray(index).isItalic = False Then
            SubtitleArray(index).propertiesString = "B"
        ElseIf SubtitleArray(index).isBold = False And SubtitleArray(index).isItalic = True Then
            SubtitleArray(index).propertiesString = "I"
        ElseIf SubtitleArray(index).isBold = False And SubtitleArray(index).isItalic = False Then
            SubtitleArray(index).propertiesString = ""
        End If

    End Sub

    Public Sub convertPropertiesStringToProperties()

        Select Case SubtitleArray(currentIndex).propertiesString
            Case "BI"
                SubtitleArray(currentIndex).isBold = True
                SubtitleArray(currentIndex).isItalic = True
            Case "B"
                SubtitleArray(currentIndex).isBold = True
                SubtitleArray(currentIndex).isItalic = False
            Case "I"
                SubtitleArray(currentIndex).isBold = False
                SubtitleArray(currentIndex).isItalic = True
            Case ""
                SubtitleArray(currentIndex).isBold = False
                SubtitleArray(currentIndex).isItalic = False
        End Select

    End Sub

    Public Sub convertPropertiesStringToProperties(ByVal index As Integer)

        Select Case SubtitleArray(index).propertiesString
            Case "BI"
                SubtitleArray(index).isBold = True
                SubtitleArray(index).isItalic = True
            Case "B"
                SubtitleArray(index).isBold = True
                SubtitleArray(index).isItalic = False
            Case "I"
                SubtitleArray(index).isBold = False
                SubtitleArray(index).isItalic = True
            Case ""
                SubtitleArray(index).isBold = False
                SubtitleArray(index).isItalic = False
        End Select

    End Sub

    Public Sub passArrayToDataGridView()
        For i = 0 To SubtitleArray.Count - 1
            frmMain.dgvSubtitles.Rows.Add(SubtitleArray(i).ID, SubtitleArray(i).showTime, SubtitleArray(i).hideTime, SubtitleArray(i).text, SubtitleArray(i).propertiesString)
        Next
    End Sub

    Public Sub passArrayToDataGridView(ByVal clearBeforeAdding As Boolean)
        If clearBeforeAdding = True Then
            frmMain.dgvSubtitles.Rows.Clear()
        End If
        For i = 0 To SubtitleArray.Count - 1
            frmMain.dgvSubtitles.Rows.Add(SubtitleArray(i).ID, SubtitleArray(i).showTime, SubtitleArray(i).hideTime, SubtitleArray(i).text, SubtitleArray(i).propertiesString)
        Next
    End Sub

    Public Sub passLineToDataGridView(ByVal row As Integer)
        frmMain.dgvSubtitles.Rows(row).SetValues(SubtitleArray(row).ID, SubtitleArray(row).showTime, SubtitleArray(row).hideTime, SubtitleArray(row).text, SubtitleArray(row).propertiesString)
    End Sub

    Public Sub addNewLineToDataGridView(ByVal row As Integer)
        frmMain.dgvSubtitles.Rows.Add(New String() {SubtitleArray(row).ID, SubtitleArray(row).showTime, SubtitleArray(row).hideTime, SubtitleArray(row).text, SubtitleArray(row).propertiesString})
    End Sub
    Public Sub passDataGridViewToArray()
        For i = 0 To frmMain.dgvSubtitles.RowCount - 1
            setID(i, frmMain.dgvSubtitles.Rows(i).Cells("subIndex").Value)
            setShowTime(i, frmMain.dgvSubtitles.Rows(i).Cells("subShow").Value)
            setHideTime(i, frmMain.dgvSubtitles.Rows(i).Cells("subHide").Value)
            setText(i, frmMain.dgvSubtitles.Rows(i).Cells("subText").Value)
            setPropertiesString(i, frmMain.dgvSubtitles.Rows(i).Cells("subProperties").Value)
        Next
    End Sub

    Public Sub passLineToArray(ByVal row As Integer)
        setID(row, frmMain.dgvSubtitles.Rows(row).Cells("subIndex").Value)
        setShowTime(row, frmMain.dgvSubtitles.Rows(row).Cells("subShow").Value)
        setHideTime(row, frmMain.dgvSubtitles.Rows(row).Cells("subHide").Value)
        setText(row, frmMain.dgvSubtitles.Rows(row).Cells("subText").Value)
        setPropertiesString(row, frmMain.dgvSubtitles.Rows(row).Cells("subProperties").Value)
    End Sub

    Private Sub resetFPSsetting()
        frmMain.CurFPS15ToolStripMenuItem.Checked = False
        frmMain.CurFPS20ToolStripMenuItem.Checked = False
        frmMain.CurFPS23976ToolStripMenuItem.Checked = False
        frmMain.CurFPS24ToolStripMenuItem.Checked = False
        frmMain.CurFPS25ToolStripMenuItem.Checked = False
        frmMain.CurFPS2997ToolStripMenuItem.Checked = False
        frmMain.CurFPS30ToolStripMenuItem.Checked = False
    End Sub

    ' Support for various formats.
    Private Sub LoadSRTSubRip()

        Dim currentLine As String

        subsCount = 0

        While Not subsFileReader.EndOfStream
            currentLine = subsFileReader.ReadLine
            If Not currentLine = "" Then
                currentLine = subsFileReader.ReadLine
                currentLine = subsFileReader.ReadLine
                currentLine = subsFileReader.ReadLine
                If Not currentLine = "" Then
                    currentLine = subsFileReader.ReadLine
                    If Not currentLine = "" Then
                        currentLine = subsFileReader.ReadLine()
                    End If
                End If
                subsCount += 1
            End If
        End While

        currentIndex = -1

        ReDim SubtitleArray(subsCount - 1)

        subsFileReader.Close()
        subsFileReader = My.Computer.FileSystem.OpenTextFileReader(frmMain.dlgSubOpen.FileName, subEncoding)

        While Not subsFileReader.EndOfStream

            currentLine = subsFileReader.ReadLine
            If Not currentLine = "" Then
                currentIndex += 1
                SubtitleArray(currentIndex).ID = currentLine

                currentLine = subsFileReader.ReadLine
                subTextParts = Split(currentLine, " --> ", "2")
                setShowTime(currentIndex, subTextParts(0))
                setHideTime(currentIndex, subTextParts(1))

                ReDim subTextParts(2)
                subTextParts(0) = ""
                subTextParts(1) = ""
                subTextParts(2) = ""

                subTextParts(0) = subsFileReader.ReadLine
                subTextParts(1) = subsFileReader.ReadLine
                If Not subTextParts(1) = "" Then
                    subTextParts(1) = " | " & subTextParts(1)
                    subTextParts(2) = subsFileReader.ReadLine
                    If Not subTextParts(2) = "" Then
                        subTextParts(2) = " | " & subTextParts(2)
                    Else
                        ReDim Preserve subTextParts(1)
                    End If
                Else
                    ReDim Preserve subTextParts(0)
                End If

                parseProperties(subTextParts)

                Select Case subTextParts.Length
                    Case 1
                        setText(currentIndex, subTextParts(0))
                    Case 2
                        setText(currentIndex, subTextParts(0) & subTextParts(1))
                    Case 3
                        setText(currentIndex, subTextParts(0) & subTextParts(1) & subTextParts(2))
                End Select


                addToDebugList(loadStringFromLangFile("counterline") & " " & SubtitleArray(currentIndex).ID)

            End If
        End While

    End Sub

    Public Function miniLoadSRTSubRip() As SubtitleType
        Dim testSubtitle As New SubtitleType

        Try
            subsFileReader = My.Computer.FileSystem.OpenTextFileReader(frmMain.dlgSubOpen.FileName, subEncoding)

            currentLine = subsFileReader.ReadLine
            If Not currentLine = "" Then
                testSubtitle.ID = currentLine

                currentLine = subsFileReader.ReadLine
                subTextParts = Split(currentLine, " --> ", "2")
                testSubtitle.showTime = subTextParts(0)
                testSubtitle.hideTime = subTextParts(1)

                ReDim subTextParts(2)
                subTextParts(0) = ""
                subTextParts(1) = ""
                subTextParts(2) = ""

                subTextParts(0) = subsFileReader.ReadLine
                subTextParts(1) = subsFileReader.ReadLine
                If Not subTextParts(1) = "" Then
                    subTextParts(2) = subsFileReader.ReadLine
                    If subTextParts(2) = "" Then
                        ReDim Preserve subTextParts(1)
                    End If
                Else
                    ReDim Preserve subTextParts(0)
                End If

                Select Case subTextParts.Length
                    Case 1
                        testSubtitle.text = subTextParts(0)
                    Case 2
                        testSubtitle.text = subTextParts(0) & newLine & subTextParts(1)
                    Case 3
                        testSubtitle.text = subTextParts(0) & newLine & subTextParts(1) & newLine & subTextParts(2)
                End Select

            End If

            Return testSubtitle

        Catch

            testSubtitle.ID = -1
            Return testSubtitle

        End Try

    End Function

    Private Sub SaveSRTSubRip()

        Dim subText(2) As String

        For i = 0 To frmMain.dgvSubtitles.Rows.Count - 1
            fileWriter.WriteLine(SubtitleArray(i).ID)
            fileWriter.WriteLine(SubtitleArray(i).showTime & " --> " & SubtitleArray(i).hideTime)

            subText = Split(SubtitleArray(i).text, " | ", 3)

            If subText.Count = 1 Then
                fileWriter.WriteLine(subText(0))
            ElseIf subText.Count = 2 Then
                fileWriter.WriteLine(subText(0) & newLine & subText(1))
            ElseIf subText.Count = 3 Then
                fileWriter.WriteLine(subText(0) & newLine & subText(1) & newLine & subText(2))
            End If

            fileWriter.WriteLine()
        Next

    End Sub

End Class
